#!/usr/bin/env python
# -*- coding:utf-8 -*-
# author : liuyu
# date : 2018/11/19 0019

import xmlrpc.client,time,os


'''
需要在cobbler 服务端的 /usr/bin/cobblerd  文件的 import 下一行增加

reload(sys)
sys.setdefaultencoding('utf8')

解决ks内容出现中文的bug
'''
class CobblerApi(object):
    def __init__(self,server,user,passwd):
        self.server = server
        self.user = user
        self.passwd = passwd
        self.token = ''
        self.info=self.__get_token()


    def __call__(self, *args, **kwargs):
        self.__sync_cobbler()
        self.remote_server.logout(self.token)

    def end(self):
        self.remote_server.logout(self.token)

    def is_kickstart_in_use(self,name):
        return self.remote_server.is_kickstart_in_use(name)

    def is_snippets_in_use(self,name,kickstart_templates):
        snsname = os.path.basename(name)
        snsname="$SNIPPET('{}')".format(snsname)
        for ks in kickstart_templates:
            # print(ks.get("kickstart"))
            context = self.read_or_write_kickstart_template(ks.get("kickstart"),"",True)
            if snsname in context:
                return True,kickstart_templates
        return False,kickstart_templates

    '''
    通过list 的格式返回每个类别的名称
    '''
    def __check_token(self):
        return self.remote_server.token_check(self.token)

    def __get_token(self):
        try:
            self.remote_server = xmlrpc.client.Server("http://{}/cobbler_api".format(self.server))
            self.token = self.remote_server.login(self.user, self.passwd)
        except Exception as e:
            print(e)
            return ('URL:%s no access' % self.server)

    def find_distros(self):
        return self.remote_server.find_distro()

    def find_profiles(self):
        return self.remote_server.find_profile()

    def find_system(self):
        return self.remote_server.find_system()

    '''
    通过list 的格式返回每个名称的详细信息
    '''
    def get_distros(self,name):
        return self.remote_server.get_distro(name)

    def get_profiles(self,name):
        return self.remote_server.get_profile(name)

    def get_system(self,name):
        return self.remote_server.get_system(name)

    '''
    删除
    '''

    # prof_id = remote_server.new_profile(token)  # 创建一个新的profile 并保存
    def remove_profile(self,name):
        self.remote_server.remove_profile(name,self.token)
        self.__sync_cobbler()

    def remove_distros(self,name):
        self.remote_server.remove_distro(name,self.token)
        self.__sync_cobbler()

    def remove_system(self,name):
        print(name)
        self.remote_server.remove_system(name,self.token)
        self.__sync_cobbler()

    '''
    修改
    '''
    def modify_profile(self,name,key,value):
        object_id = self.remote_server.get_profile_handle(name, self.token)
        # remote_server.modify_profile(prof_id,'name','vm_test1',token) # 修改prof_id指定的profile 名称
        # remote_server.modify_profile(prof_id,'distro','centos6.8-x86_64',token)  # 也是修改prof_id的信息
        # remote_server.modify_profile(object_id, 'kickstart', '/var/lib/cobbler/kickstarts/sample_end.ks', token)
        try:
            self.remote_server.modify_profile(object_id, key, value, self.token)
            self.remote_server.save_profile(object_id, self.token)  # 保存
            self.__sync_cobbler()

        except Exception as e:
            return e

    def modify_system(self,name,key,value):
        object_id = self.remote_server.get_system_handle(name, self.token)
        try:
            self.remote_server.modify_system(object_id, key, value, self.token)
            self.remote_server.save_system(object_id, self.token)  # 保存
            self.__sync_cobbler()

        except Exception as e:
            return e

    def modify_distros(self,name,key,value):
        object_id = self.remote_server.get_distros_handle(name, self.token)
        try:
            self.remote_server.modify_distros(object_id, key, value, self.token)
            self.remote_server.save_distros(object_id, self.token)  # 保存
            self.__sync_cobbler()

        except Exception as e:
            return e

    '''
    获取ks和sns 的文件列表
    '''
    def get_kickstart_templates(self):

        kickstartlist =[]
        for ks in self.remote_server.get_kickstart_templates():
            if ks.startswith('/'):
                if self.is_kickstart_in_use(ks):
                    status="in-use"
                else:
                    status = "not-in-use"
                kickstartlist.append({"kickstart":ks,"status":status})

        return kickstartlist


    def get_snippets(self):
        snippetslist =[]
        kickstart_templates=self.get_kickstart_templates()
        for sns in self.remote_server.get_snippets():
            if sns.startswith('/'):
                status,kickstart_templates=self.is_snippets_in_use(sns,kickstart_templates)
                if status:
                    status="in-use"
                else:
                    status = "not-in-use"
                snippetslist.append({"snippets":sns,"status":status})

        return snippetslist

    # 同步cobbler修改后的信息，这个做任何操作后，都要必须有
    def __sync_cobbler(self):
        return self.remote_server.sync(self.token) # 同步cobbler修改后的信息，这个做任何操作后，都要必须有

    '''
    填写ks模板
        # print(remote_server.read_or_write_kickstart_template('/var/lib/cobbler/kickstarts/1234.ks',False,'123\ndead\tdd\nda',token))
        替换KS字符串如果为-1，将删除此Ks文件，条件是此ks文件已不在引用
    '''
    def read_or_write_kickstart_template(self,filename,context,read=False):
        fullfilepath = os.path.join('/var/lib/cobbler/kickstarts/',filename)
        #not self.remote_server.is_kickstart_in_use(fullfilepath) and
        if not os.path.exists(fullfilepath):
            return self.remote_server.read_or_write_kickstart_template(fullfilepath,read,context,self.token)
        else:
            return "The kickstart is exists"

    '''
    填写sns模板
     # print(remote_server.read_or_write_snippet('/var/lib/cobbler/snippets/test1',False,'zhaoyong_test',token)) # 在snippgets下建立脚本文件
    '''
    def read_or_write_snippet(self,filename,context,read=False):
        fullfilepath = os.path.join('/var/lib/cobbler/snippets/',filename)
        if not os.path.exists(fullfilepath):
            return self.remote_server.read_or_write_snippet(fullfilepath,read,context,self.token)
        else:
            return "The snippet is exists"

    '''
    增加新的system
    '''
    def create_or_update_system(self,name,mac,ip,profile,subnet,gateway,interface,hostname,dns,netboot_enabled,password,
                                kickstart='/var/lib/cobbler/kickstarts/sample_end.ks',
                                kops='net.ifnames=0 biosdevname=0'):
        sid = self.remote_server.new_system(self.token)
        self.remote_server.modify_system(sid,'name',name,self.token)
        self.remote_server.modify_system(sid, 'hostname', hostname, self.token)
        self.remote_server.modify_system(sid, 'gateway', gateway, self.token)
        self.remote_server.modify_system(sid, 'profile', profile, self.token)
        self.remote_server.modify_system(sid, 'name_servers', dns, self.token)
        self.remote_server.modify_system(sid, 'modify_interface', {
            "macaddress-{}".format(interface): mac.upper(),
            "ipaddress-{}".format(interface): ip,
            "gateway-{}".format(interface): gateway,
            "subnet-{}".format(interface):subnet,
            "dnsname-{}".format(interface): ip,
            "static-{}".format(interface): True,
        }, self.token)
        self.remote_server.modify_system(sid,'kickstart',kickstart,self.token)
        self.remote_server.modify_system(sid,'kopts',kops,self.token)
        self.remote_server.modify_system(sid,'netboot_enabled',netboot_enabled,self.token)
        self.remote_server.modify_system(sid,'power_pass',password,self.token)
        self.remote_server.save_system(sid,self.token)
        self.__sync_cobbler()

    '''
    获取system ks 定义文件
    '''
    def get_system_generate_kickstart(self,system):
        return self.remote_server.generate_kickstart('',system)

    '''
    获取profile ks 定义文件
    '''
    def get_profile_generate_kickstart(self,profile):
        return self.remote_server.generate_kickstart(profile)

    def get_status(self):
        # print(self.remote_server.get_status('text',self.token))
        # print(self.remote_server.get_status("normal",self.token))
        return self.remote_server.get_status('json',self.token)

    def get_system_status(self,name):
        for ip,v in self.remote_server.get_status('json',self.token).items():
            if v[2].split(":")[1] == name:
                start = totime(v[0])
                end = ""
                if v[1] != -1:
                    end = totime(v[1])
                system_name = v[2].split(":")[1]
                status = v[5]
                initcount = v[3]
                successcount = v[4]
                infos= {"starttime":start,"endtime":end,"ip":ip,
                        "systemname":system_name,"status":status,
                        "initcount":initcount,"successcount":successcount}
                return infos
        return False
    def get_settings(self):
        return self.remote_server.get_settings()

class init_system_api(CobblerApi):

    @staticmethod
    def run():
        from DevOps import models
        cobblerserverobj = models.CobblerServer.objects.get()
        return CobblerApi(cobblerserverobj.host,cobblerserverobj.username,cobblerserverobj.password)

def totime(timeStamp):
    timeArray = time.localtime(timeStamp)
    otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
    return otherStyleTime

if __name__ == '__main__':
    time_str = time.time()
    server = '192.168.5.50'
    user = 'cobbler'
    passwd = 'cobbler'
    cobbler = CobblerApi(server,user,passwd)
    # print(cobbler.find_system())
    # print(cobbler.find_distros())
    # print(cobbler.find_profiles())
    # print(cobbler.get_system('kvm-centos7-test'))
    # cobbler.remove_system('centos-nineven')
    info=cobbler.get_system('cobb_test_nieven.com-192.168.5.23')
    if info == "~":
        print("不存在")
    else:
        print(info)
    # print(cobbler.remove_system('111'))
    #
    # infos = cobbler.get_system('centos-nineven')
    # print(infos.get("name"))
    # print(infos.get("profile"))
    # print(infos.get("kickstart"))
    # print(infos.get("kernel_options"))
    # for k,v in infos.get("interfaces").items():
    #     print(k)
    #     print(v.get("gateway"))
    #     print(v.get("hostname"))
    #     print(v.get("mac_address"))
    #     print(v.get("netmask"))
    #     print(v.get("ip_address"))
    # print(cobbler.get_status())
    system_status = cobbler.get_settings()
    print(system_status)
    exit()

    for ip,v in system_status.items():
        start = totime(v[0])
        end=""
        if v[1] !=-1:
            end = totime(v[1])
        system_name = v[2]
        status = v[5]
        # v[4] 安装系统成功的次数  ，v[3] 安装次数
        print(ip,v)
        print('''
        ip:             %s
        start:          %s
        end:            %s
        system_name:    %s
        status:         %s
        '''%(ip,start,end,system_name,status))


    # print(cobbler.get_system_generate_kickstart('Centos-7.2-mini-x86_64'))
    # print(cobbler.get_profiles(cobbler.get_system('centos-nineven').get("profile")))
    # print(cobbler.modify_profile('Centos-7.2-mini-x86_64','kopts','net.ifnames=0 biosdevname=0'))
    print(cobbler.create_or_update_system("centos-nineven","00:50:56:39:E6:FE","192.168.5.82","Centos-7.2-mini-x86_64",
                             "255.255.255.0","192.168.5.1","eth0","nineven-test","114.114.114.114"))
    # print(cobbler.remove_system("centos-nineven"))

